﻿class BsMap {
    constructor(mapType, coord) {
        this._coord = coord;
        this.mapType = mapType;
        this.makerIndex = 0;
    }

    /**
    * 获取地图当前对象
    */
    get map() {
        return this._map;
    }

    set map(v) {
        this._map = v;
    }

    /**
    * 获取地图当前坐标系统
    */
    get coord() {
        return this._coord;
    }

    set coord(v) {
        this._coord = v;
    }

    /**
    * 设置中心点
    * @param point 点坐标，Point类型
    */
    center(point) {

    }

    /**
    * 地图缩放
    * @param zoom 缩放比例
    */
    zoom(zoom) {

    }

    /**
    * 添加点标记
    * @param point 点坐标，Point类型
    * @param icon 图标对象，由方法 createMarkerIcon 返回
    * @labelContent 标记文本
    * @labelStyle 文本样式
    * @param infoWindow 信息窗口，由方法 createInfoWindow 返回，可选参数
    */
    addMarker(p, icon, labelContent, labelStyle, infoWindow) {

    }

    /**
    * 创建图标对象
    * @param iconUrl 图标URL
    * @param width 宽度
    * @param height 高度
    * @param anchor 图片锚点，可选值有  'top-left'、'top-center'、'top-right'、'middle-left'、'center'、'middle-right'、'bottom-left'、'bottom-center'、'bottom-right' ， 分别代表了点标记锚点的不同方位。
    */
    createMarkerIcon(iconUrl, width, height, anchor) {

    }

    /**
    * 创建文本样式
    * @param color 颜色
    * @param size 字体大小
    * @param offset 位置偏移，{x,y}
    */
    createMarkerLabelStyle(color, size, offset) {

    }


    /**
    * 转换图标锚点名字为具体值
    * @param anchor 图片锚点，可选值有  'top-left'、'top-center'、'top-right'、'middle-left'、'center'、'middle-right'、'bottom-left'、'bottom-center'、'bottom-right' ， 分别代表了点标记锚点的不同方位。
    * @param width 宽度
    * @param height 高度
   */
    convertAnchor(anchor, width, height) {
        var x = 0;
        var y = 0;
        if (anchor.indexOf("center")) {
            x = width / 2;
        } else if (anchor.indexOf("right")) {
            x = width;
        }
        if (anchor.indexOf("middle")) {
            y = height / 2;
        } else if (anchor.indexOf("bottom")) {
            y = height;
        }
        var r = { x: x, y: y };
        console.dir(r);
        return r;
    }

    /**
    * 创建信息窗口
    * @param opts 窗口参数，包含属性（title,content,width,height,point）
    * @param icon 图标对象，不同地图对象具体属性不同 
    */
    createInfoWindow(opts, icon) {

    }


    //构建自定义信息窗体
    createInfoWindowContent(title, content) {
        var info = document.createElement("div");
        info.className = "custom-info input-card content-window-card";

        //可以通过下面的方式修改自定义窗体的宽高
        info.style.width = "300px";
        // 定义顶部标题
        var top = document.createElement("div");
        var titleD = document.createElement("div");
        var closeX = document.createElement("img");
        top.className = "info-top";
        titleD.innerHTML = title;

        top.appendChild(titleD);
        info.appendChild(top);

        // 定义中部内容
        var middle = document.createElement("div");
        middle.className = "info-middle";
        middle.style.backgroundColor = 'white';
        middle.innerHTML = content;
        info.appendChild(middle);

        // 定义底部内容
        var bottom = document.createElement("div");
        bottom.className = "info-bottom";
        bottom.style.position = 'relative';
        bottom.style.top = '0px';
        bottom.style.margin = '0 auto';
        info.appendChild(bottom);
        return info.outerHTML;
    }

    /**
    * 当前位置
    * @returns
    */
    currentPoint() {

    }

    /**
    * 地图按点坐标自适应
    * @param points 点数组
    * @returns 
    */
    fitPoints(points) {

    }

    /**
    * 转换点坐标为当前地图类型的点对象
    * @param point 点坐标，Point类型
    */
    pointConvert(p) {

    }

    /**
    * 坐标系转换
    * WGS84 
    * BD09  百度
    * GCJ02 国测局坐标 火星坐标系 高德，腾讯
    * 支持 WGS84->GCJ02 WGS84->BD09
    * 支持 BD09->GCJ02
    * 支持 GCJ02->BD09
    * @param lng
    * @param lat
    * @param sc 来源坐标系统
    * @returns {*[]}
    */
    coordConvert(lng, lat, sc) {
        if (!sc) sc = "WGS84";
        sc = sc.toUpperCase();
        var dc = this.coord; //当前地图坐标系统
        dc = dc.toUpperCase();
        if (sc == "BD09" && dc == "GCJ02")
            return bd9ToGcj02(lng, lat);
        if (sc == "GCJ02" && dc == "BD09")
            return gcj02ToBd09(lng, lat);
        if (sc == "WGS84") {
            if (dc == "GCJ02")
                return wgs84ToGcj02(lng, lat);
            if (dc == "BD09") {
                var p = wgs84ToGcj02(lng, lat);
                return gcj02ToBd09(p[0], p[1]);
            }
        }
        console.log('未能转换坐标系');
        return [lng, lat]; //未转换，返回原坐标
    }
}

/**
 * 提供了百度坐标（BD09）、国测局坐标（火星坐标，GCJ02）、和WGS84坐标系之间的转换
 */

//定义一些常量
var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
var PI = 3.1415926535897932384626;
var a = 6378245.0;
var ee = 0.00669342162296594323;

/**
 * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
 * 即 百度 转 谷歌、高德、腾讯
 * @param bd_lon
 * @param bd_lat
 * @returns {*[]}
 */
function bd9ToGcj02(bd_lon, bd_lat) {
    var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    var x = bd_lon - 0.0065;
    var y = bd_lat - 0.006;
    var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
    var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
    var gg_lng = z * Math.cos(theta);
    var gg_lat = z * Math.sin(theta);
    return [gg_lng, gg_lat]
}

/**
 * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
 * 即谷歌、高德、腾讯 转 百度
 * @param lng
 * @param lat
 * @returns {*[]}
 */
function gcj02ToBd09(lng, lat) {
    var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
    var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
    var bd_lng = z * Math.cos(theta) + 0.0065;
    var bd_lat = z * Math.sin(theta) + 0.006;
    return [bd_lng, bd_lat]
}

/**
 * WGS84转GCj02
 * @param lng
 * @param lat
 * @returns {*[]}
 */
function wgs84ToGcj02(lng, lat) {
    if (out_of_china(lng, lat)) {
        return [lng, lat]
    }
    else {
        var dlat = transformlat(lng - 105.0, lat - 35.0);
        var dlng = transformlng(lng - 105.0, lat - 35.0);
        var radlat = lat / 180.0 * PI;
        var magic = Math.sin(radlat);
        magic = 1 - ee * magic * magic;
        var sqrtmagic = Math.sqrt(magic);
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
        var mglat = lat + dlat;
        var mglng = lng + dlng;
        return [mglng, mglat]
    }
}

/**
 * GCJ02 转换为 WGS84
 * @param lng
 * @param lat
 * @returns {*[]}
 */
function gcj02ToWgs84(lng, lat) {
    if (out_of_china(lng, lat)) {
        return [lng, lat]
    }
    else {
        var dlat = transformlat(lng - 105.0, lat - 35.0);
        var dlng = transformlng(lng - 105.0, lat - 35.0);
        var radlat = lat / 180.0 * PI;
        var magic = Math.sin(radlat);
        magic = 1 - ee * magic * magic;
        var sqrtmagic = Math.sqrt(magic);
        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
        mglat = lat + dlat;
        mglng = lng + dlng;
        return [lng * 2 - mglng, lat * 2 - mglat]
    }
}

function transformlat(lng, lat) {
    var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
    ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
    return ret
}

function transformlng(lng, lat) {
    var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
    ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
    ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
    return ret
}

/**
 * 判断是否在国内，不在国内则不做偏移
 * @param lng
 * @param lat
 * @returns {boolean}
 */
function out_of_china(lng, lat) {
    return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
}

class Point {
    constructor(lng, lat) {
        this.lng = lng;
        this.lat = lat;
    }
}

class Marker {
    constructor(lng, lat) {
        this.lng = lng;
        this.lat = lat;
    }
}
